# -*- coding: utf-8 -*-
import logging
import sys
from pylons import request, response, session, tmpl_context as c, url, app_globals as g
from pylons.controllers.util import abort, redirect
from pylons.configuration import asbool
from pylons.decorators.cache import beaker_cache
from pylons import cache
from repoze.what.plugins.pylonshq import ControllerProtector, ActionProtector
from repoze.what.predicates import in_group, is_user, has_permission

from craneserver.lib.base import BaseController, render
import simplejson



log = logging.getLogger(__name__)

class CommandQueueController(BaseController):

    def available_commands(self, format='json'):
        uid = c.identity['user'].uid
        nocache = asbool(request.params.get('nocache', False))
        @g.cache.region('memcached', uid, str(sys._getframe().f_code.co_name))
        def _available_commands(format):
            result = g.command_queue.available_commands()
            if format == 'json':
                return simplejson.dumps(result)
            elif format == 'raw':
                return result
            elif format == 'xml':
                c.title = str(sys._getframe().f_code.co_name)
                c.content = result
                return render('output.mako')
        if nocache:
            g.cache.region_invalidate(available_commands, None, uid, str(sys._getframe().f_code.co_name), format)

        return _available_commands(format)

    def execute(self, command, site=None, format='json'):
        kwargs = dict(request.params)
        result = g.command_queue.execute(command, site, **kwargs)
        if format == 'json':
            return simplejson.dumps(result.task_id)
        elif format == 'raw':
            return result.task_id
        elif format == 'xml':
            c.title = str(sys._getframe().f_code.co_name)
            c.content = result.task_id
            return render('output.mako')

    def execute_wait(self, command, timeout=None, site=None, format='json'):
        kwargs = dict(request.params)
        result = g.command_queue.execute(command, site, **kwargs)
        try:
            if format == 'json':
                return simplejson.dumps(result.wait(timeout))
            elif format == 'raw':
                return result.wait(timeout)
            elif format == 'xml':
                c.title = str(sys._getframe().f_code.co_name)
                c.content = result.wait(timeout)
                return render('output.mako')
        except Exception as ex:
            print repr(ex)
            response.status = 408
            if format == 'json':
                return simplejson.dumps({'id':result.task_id, 'status':result.status, 'exception': repr(ex), 'traceback':result.traceback})
            elif format == 'raw':
                return {'id':result.task_id, 'status':result.status, 'exception': repr(ex), 'traceback':result.traceback}
            elif format == 'xml':
                c.title = str(sys._getframe().f_code.co_name)
                c.id = result.task_id
                c.status = result.status
                c.traceback = result.traceback
                return render('output.mako')

    @beaker_cache(type='memory', expire=15, query_args=True, invalidate_on_startup=True)
    def execute_wait_cacheable(self, command, timeout=None, site=None, format='json'):
        kwargs = dict(request.params)
        result = g.command_queue.execute(command, site, **kwargs)
        try:
            if format == 'json':
                return simplejson.dumps(result.wait(timeout))
            elif format == 'raw':
                return result.wait(timeout)
            elif format == 'xml':
                c.title = str(sys._getframe().f_code.co_name)
                c.content = result.wait(timeout)
                return render('output.mako')
        except Exception as ex:
            response.status = 408
            if format == 'json':
                return simplejson.dumps({'id':result.task_id, 'status':result.status, 'exception': repr(ex), 'traceback':result.traceback})
            elif format == 'raw':
                return {'id':result.task_id, 'status':result.status, 'exception': repr(ex), 'traceback':result.traceback}
            elif format == 'xml':
                c.title = str(sys._getframe().f_code.co_name)
                c.id = result.task_id
                c.status = result.status
                c.traceback = result.traceback
                return render('output.mako')

    def cancel(self, commandUuid, format='json'):
        result = g.command_queue.cancel(commandUuid)
        if format == 'json':
            return simplejson.dumps(result)
        elif format == 'raw':
                return result
        elif format == 'xml':
            c.title = str(sys._getframe().f_code.co_name)
            c.content = result
            return render('output.mako')

    def status(self, commandUuid, format='json'):
        result = g.command_queue.status(commandUuid)
        if format == 'json':
            return simplejson.dumps(result)
        elif format == 'raw':
                return result
        elif format == 'xml':
            c.title = str(sys._getframe().f_code.co_name)
            c.content = result
            return render('output.mako')

    def ready(self, commandUuid, format='json'):
        result = g.command_queue.ready(commandUuid)
        if format == 'json':
            return simplejson.dumps(result)
        elif format == 'raw':
                return result
        elif format == 'xml':
            c.title = str(sys._getframe().f_code.co_name)
            c.content = result
            return render('output.mako')

    def successful(self, commandUuid, format='json'):
        result = g.command_queue.successful(commandUuid)
        if format == 'json':
            return simplejson.dumps(result)
        elif format == 'raw':
                return result
        elif format == 'xml':
            c.title = str(sys._getframe().f_code.co_name)
            c.content = result
            return render('output.mako')

    def failed(self, commandUuid, format='json'):
        try:
            result = g.command_queue.failed(commandUuid)
        except:
            result = False
        if format == 'json':
            return simplejson.dumps(result)
        elif format == 'raw':
                return result
        elif format == 'xml':
            c.title = str(sys._getframe().f_code.co_name)
            c.content = result
            return render('output.mako')

    def traceback(self, commandUuid, format='json'):

        uid = c.identity['user'].uid
        nocache = asbool(request.params.get('nocache', False))
        @g.cache.region('memcached', uid, str(sys._getframe().f_code.co_name))
        def _traceback(commandUuid, format):
            result = g.command_queue.traceback(commandUuid)
            if format == 'json':
                return simplejson.dumps(result)
            elif format == 'raw':
                return result
            elif format == 'xml':
                c.title = str(sys._getframe().f_code.co_name)
                c.content = result
                return render('output.mako')
        if nocache:
            g.cache.region_invalidate(traceback, None, uid, str(sys._getframe().f_code.co_name), commandUuid, format)

        return _traceback(commandUuid, format)

    def result(self, commandUuid, format='json'):

        uid = c.identity['user'].uid
        nocache = asbool(request.params.get('nocache', False))
        @g.cache.region('memcached', uid, str(sys._getframe().f_code.co_name))
        def _result(commandUuid, format):
            result = g.command_queue.result(commandUuid)
            if format == 'json':
                return simplejson.dumps(result)
            elif format == 'raw':
                return result
            elif format == 'xml':
                c.title = str(sys._getframe().f_code.co_name)
                c.content = result
                return render('output.mako')
        if nocache:
            g.cache.region_invalidate(result, None, uid, str(sys._getframe().f_code.co_name), commandUuid, format)

        return _result(commandUuid, format)
